﻿namespace BEGDC.CC.Web.EZVisit.Common
{
    #region Using Directives

    using System;
    using System.IO;
    using System.Security.Principal;
    using ASBCC.Database.Entity;
    using ASBCC.Database.Service;
    using ASBCC.Utility;
    using BL.Common;
    using Controls;
    using UserControls;
    using Utility.Castle;
    using Utility.Extensions;
    using Workflow;
    using Configuration = BL.Workflow.Configuration;

    #endregion

    public partial class EZVRequestUpload : BasePage
    {
        private const string AllowedFilesTypes = "TXT;MSG;EML;PPT;DOC;XLS;DOCX;XLSX;PPTX;PDF;RAR;ZIP";

        private string ApplicationSessionKey
        {
            get
            {
                return this.Request.QueryString["sn"];
            }
        }

        private string AttchType
        {
            get
            {
                return this.Request.QueryString["attchType"];
            }
        }

        private EZVisitApplicationTableEntity Application
        {
            get
            {
                return this.Session[this.ApplicationSessionKey] as EZVisitApplicationTableEntity;
            }
            set
            {
                this.Session[this.ApplicationSessionKey] = value;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (this.Application == null)
            {
                return;
            }

            // Save application before upload
            if (this.Application.AppIDIsNull())
            {
                var app = this.Application;
                app.AppNo = EZVRequestBaseControl.GenerateAppNo(null, app.AllDept, app.Account, true);

                EZVisitApplicationManager.Insert(app);
                this.Application = app;
            }

            try
            {
                string error = this.SaveAttachment();

                if (error.IsNotNullOrWhiteSpace())
                {
                    this.Response.Write("<script type=\"text/javascript\">alert('" + error + "');</script>");
                }
                else
                {
                    this.Response.Write(@"<script type=""text/javascript"">window.close();window.returnValue='reload';</script>");
                }
            }
            catch
            {
                this.Response.Write("<script type=\"text/javascript\">alert('Unknown error occured, please contact system admin.');</script>");
            }
        }

        private string SaveAttachment()
        {
            string error;

            var attachment = this.UploadFile(out error);

            if (attachment != null)
            {
                UploadFileManager.Insert(attachment);
            }

            return error;
        }

        private static bool AttachmentExists(int appID, string attchType)
        {
            string condition = string.Format("AppID={0} and AttachmentTypeKey='{1}' and IsEnabled=1", appID, attchType);
            var attachments = UploadFileManager.SelectByCondition(condition);

            return attachments.Count > 0;
        }

        private UploadFileTableEntity UploadFile(out string error)
        {
            error = string.Empty;

            if (this.AttchType.IsNotNullOrWhiteSpace() && (this.edt_UploadGifts.PostedFile != null && this.edt_UploadGifts.PostedFile.FileName.IsNotNullOrWhiteSpace()))
            {
                var utilityService = (IUtility)AppContainer.Instance[ServiceConst.UtilityService];

                var attchType = utilityService.GetDicItem(this.AttchType, DicType.ATTACHMENTTYPE);

                if (attchType == null)
                {
                    error = "Invalid attachment type.";
                    return null;
                }

                if (AttachmentExists(this.Application.AppID.Value, attchType.DicItemKey))
                {
                    error = "Attachment of same type had been uploaded to the server. Please delete it before upload again.";
                    return null;
                }

                // Get EZVisitAppType ID
                int ezvAppTypeId = utilityService.GetDicItem("EZV", DicType.Application_Type).Id;

                string fileServer = ConfigUtility.UploadServerIP;
                string ezvisitFolder = ConfigUtility.EZVisitDocument;

                WindowsImpersonationContext context = UploadUtility.NetworkImpersonateUser();

                string appDocRoot = fileServer  + ezvisitFolder;

                string fullPath;
                WebUtility.GetDocumentStoredPath(appDocRoot, this.edt_UploadGifts.PostedFile.FileName, out fullPath);

                string fileName = Path.GetFileName(fullPath).Substring(5);

                // Check if the file is allowed to be uploaded
                string ext = Path.GetExtension(fileName);

                if (string.IsNullOrEmpty(ext) || !ValueIncludes(AllowedFilesTypes, ext.Substring(1)))
                {
                    error = "Invalid file type. Only allow " + AllowedFilesTypes + " files.";
                    return null;
                }

                this.edt_UploadGifts.PostedFile.SaveAs(fullPath);

                context.Undo();

                return new UploadFileTableEntity
                {
                    FileName = fileName,
                    FilePath = fullPath,
                    AppID = this.Application.AppID,
                    Owner = this.UserInfo.NameEN,
                    Date = DateTime.Now,
                    AttachmentTypeID = attchType.Id,
                    AttachmentTypeKey = attchType.DicItemKey,
                    AttachmentType = attchType.Description,
                    AppType = "EZV",
                    AppTypeID = ezvAppTypeId,
                    IsEnabled = true
                };
            }

            error = "Invalid attachment type.";
            return null;
        }

        private static bool ValueIncludes(string src, string dest)
        {
            src = ";" + src + ";";
            dest = ";" + dest + ";";
            return src.IndexOf(dest, StringComparison.InvariantCultureIgnoreCase) != -1;
        }
    }
}